/* eslint-disable react/no-deprecated */
import React from 'react';
import ReactDOM from 'react-dom';
import { Modal } from 'antd';
import { ConfigProvider } from 'antd';
import zhCN from 'antd/es/locale/zh_CN';
import _ from 'lodash';
import { destroyFns } from 'antd/lib/modal/Modal';
import type { ModalProps } from 'antd/lib/modal/Modal';
import classNames from 'classnames';
import './index.less';

const TjModal = {
  defaultProps: { notContentBorder: true } as Partial<ITjModelProps>,
  open: (props: ITjModelProps) => {
    const config = _.defaults({}, TjModal.defaultProps, props);
    const div = document.createElement('div');
    document.body.appendChild(div);

    let currentConfig = { ...config, confirmLoading: false, visible: true } as any;
    let contentHandler: any;

    let content = currentConfig.content;
    if (!_.isString(currentConfig.content.type)) {
      // 普通html元素不进行props注入，避免react警告
      content = React.cloneElement(currentConfig.content, {
        getHandler: (handler: (handler: () => any) => void) => {
          contentHandler = handler;
        },
      });
    }

    function render(props: ITjModelProps) {
      ReactDOM.render(
        <ConfigProvider locale={zhCN}>
          <Modal
            okText="确认"
            cancelText="取消"
            {...props}
            onOk={ok}
            onCancel={() => close({ triggerCancel: true })}
            className={classNames('not-header-pb', {
              'not-content-border': props.notContentBorder,
            })}
          >
            {content}
          </Modal>
        </ConfigProvider>,
        div,
      );
    }

    function ok() {
      let value: any = null;
      const inner = () => {
        if (config.onOk) {
          const result = config.onOk(value);
          if (result && _.isFunction(result.then)) {
            update({ confirmLoading: true });
            result
              .finally(() => {
                update({ confirmLoading: false });
              })
              .then(() => {
                close();
              });
          } else {
            close();
          }
        } else {
          close();
        }
      };
      if (contentHandler) {
        value = contentHandler();
        if (value && _.isFunction(value.then)) {
          update({ confirmLoading: true });
          value
            .finally(() => {
              update({ confirmLoading: false });
            })
            .then((res: any) => {
              value = res;
              inner();
            });
        } else {
          inner();
        }
      } else {
        inner();
      }
    }

    function update(newConfig: Partial<ITjModelProps>) {
      currentConfig = { ...currentConfig, ...newConfig };
      render(currentConfig);
    }

    function close(this: any, ...args: any[]) {
      currentConfig = {
        ...currentConfig,
        visible: false,
        afterClose: destroy.bind(this, ...args),
      };
      render(currentConfig);
    }

    function destroy(...args: any[]) {
      const unmountResult = ReactDOM.unmountComponentAtNode(div);
      if (unmountResult && div.parentNode) {
        div.parentNode.removeChild(div);
      }
      const triggerCancel = args.some((param) => param && param.triggerCancel);
      if (config.onCancel && triggerCancel) {
        config.onCancel(...args);
      }
      for (let i = 0; i < destroyFns.length; i++) {
        const fn = destroyFns[i];
        if (fn === close) {
          destroyFns.splice(i, 1);
          break;
        }
      }
    }

    render(currentConfig);

    destroyFns.push(close);

    return {
      destroy: close,
      update,
    };
  },
};

export interface ITjModelProps extends ModalProps {
  /**
   * 模态框内容
   */
  content: React.ReactNode;
  /**
   * OK事件
   */
  onOk?: (value: any) => void | Promise<any>;
  /**
   * Cancel事件
   */
  onCancel?: (...args: any[]) => void;
  /**
   * 隐藏header和footer的线
   */
  notContentBorder?: boolean;
}

export interface ITjModalContentProps {
  getHandler?: (handler: () => any) => void;
}

export { TjModal };
